package com.msb.mall.mallcart.service.impl;

import com.alibaba.fastjson.JSON;
import com.msb.common.constant.CartConstant;
import com.msb.common.utils.R;
import com.msb.common.vo.MemberVO;
import com.msb.mall.mallcart.Interceptor.AuthInterceptor;
import com.msb.mall.mallcart.feign.ProductFeignService;
import com.msb.mall.mallcart.service.ICartService;
import com.msb.mall.mallcart.vo.Cart;
import com.msb.mall.mallcart.vo.CartItem;
import com.msb.mall.mallcart.vo.SkuInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @Auther: huangxiaode
 * @Date: 2023/3/16 0016 - 03 - 16 - 14:53
 * @Description: com.msb.mall.mallcart.service.impl
 * @version: 1.0
 */
@Service
public class CartServiceImpl implements ICartService {

    @Autowired
    StringRedisTemplate restTemplate;

    @Autowired
    ProductFeignService productFeignService;

    @Autowired
    ThreadPoolExecutor executor;


    /**
     * 把商品添加到购物车中去
     * @param skuId
     * @param num
     * @return
     */
    @Override
    public CartItem addCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {
        BoundHashOperations<String,Object,Object> hashOperations = getCartKeyOperation();
        // 如果redis存储在商品的信息 那么我们只需要修改商品的数量即可
        Object o = hashOperations.get(skuId.toString());
        if (o!=null){
            //说明已经存在了这个商品 那么修改商品的数量即可
            String json = (String) o;
            CartItem cartItem = JSON.parseObject(json, CartItem.class);
            cartItem.setCount(cartItem.getCount()+num);
            hashOperations.put(skuId.toString(),JSON.toJSONString(cartItem));
            return cartItem;
        }
        CartItem cartItem = new CartItem();
        CompletableFuture future1 = CompletableFuture.runAsync(() -> {
            //1. 远程调用获取 商品信息
            R r = productFeignService.info(skuId);
            String skuInfoJSON = (String) r.get("skuInfoJSON");
            SkuInfoVo skuInfoVo = JSON.parseObject(skuInfoJSON, SkuInfoVo.class);
            System.out.println("skuInfoVo = " + skuInfoVo);
            cartItem.setCheck(true);
            cartItem.setCount(num);
            cartItem.setPrice(skuInfoVo.getPrice());
            cartItem.setSkuId(skuId);
            cartItem.setTitle(skuInfoVo.getSkuTitle());
            cartItem.setSpuId(skuInfoVo.getSpuId());
        }, executor);

        CompletableFuture future2 = CompletableFuture.runAsync(() -> {
            // 2. 获取商品的销售属性
            List<String> skuSaleAttrs = productFeignService.getSkuSaleAttrs(skuId);
            cartItem.setSkuAttr(skuSaleAttrs);
        }, executor);
        CompletableFuture.allOf(future1,future2).get();
        String jsonString = JSON.toJSONString(cartItem);
        hashOperations.put(skuId.toString(),jsonString);
        return cartItem;
    }

    @Override
    public Cart getCartList() {
        BoundHashOperations<String, Object, Object> operations = getCartKeyOperation();
        Set<Object> keys = operations.keys();
        Cart cart = new Cart();
        List<CartItem> list = new ArrayList<>();
        for (Object k : keys) {
            String key = (String) k;
            Object o = operations.get(key);
            String json = (String) o;
            CartItem cartItem = JSON.parseObject(json, CartItem.class);
            list.add(cartItem);
        }
        cart.setItems(list);
        return cart;
    }

    /**
     * 获取当前登录用户选中的商品信息
     * @return
     */
    @Override
    public List<CartItem> getUserCartItems() {
        BoundHashOperations<String, Object, Object> operations = getCartKeyOperation();
        List<Object> values = operations.values();
        List<CartItem> list = values.stream().map(item -> {
            String json = (String) item;
            CartItem cartItem = JSON.parseObject(json, CartItem.class);
            return cartItem;
        }).filter(item -> {
            return item.isCheck();
        }).collect(Collectors.toList());
        return list;
    }

    private BoundHashOperations<String, Object, Object> getCartKeyOperation() {
        // hash key: cart:1   skuId:cartItem
        MemberVO memberVO = AuthInterceptor.threadLocal.get();
        String cartKey = CartConstant.CART_PERFIX + memberVO.getId();
        BoundHashOperations<String, Object, Object> hashOperations = restTemplate.boundHashOps(cartKey);
        return hashOperations;
    }
}
